#ifndef _SYNCOMMON_H
#define _SYNCOMMON_H

#include "dlslib.h"
#include "mathutils.h"

//#define STREAMLINE

#include <tchar.h>
#include <math.h>

extern Audio::DLS dls;

#define OVERSAMPLE_FACTOR 1
#define INTERNAL_SAMPLE_RATE (44100 * OVERSAMPLE_FACTOR)
#define BLOCKSIZE 32

#define FORBLOCK(i) for (int i = 0; i < BLOCKSIZE; i++)

typedef float __declspec(align(16)) Block[BLOCKSIZE];

namespace Synth {

void Clear(Block buf);
void Scale(Block buf, float amount);
void AddScaled(Block dest, const Block src, float scale);
void PanVolume(Block lout, Block rout, Block lin, Block rin, float volume, float pan);
void FixDenormals(Block buf);

void AddMinBLEPStep(float *out, int count, int oversample);

enum ChannelParams { // All are single bytes
	// Affect each voice individually
	cp_Osc1Waveform,
	cp_Osc1InstrHardSync,
	cp_Osc1PulseWidth,
	cp_Osc1Transpose,
	cp_Osc1Detune,
	cp_Osc1Volume,
	cp_Osc1FM,
	cp_Osc1RingMod,
	cp_Osc1Pan,
	cp_Osc2Waveform,
	cp_Osc2InstrHardSync,
	cp_Osc2PulseWidth,
	cp_Osc2Transpose,
	cp_Osc2Detune,
	cp_Osc2Volume,
	cp_Osc2FM,
	cp_Osc2RingMod,
	cp_Osc2Pan,
	cp_Osc3Waveform, //20
	cp_Osc3InstrHardSync,
	cp_Osc3PulseWidth,
	cp_Osc3Transpose,
	cp_Osc3Detune,
	cp_Osc3Volume,
	cp_Osc3FM,
	cp_Osc3RingMod,
	cp_Osc3Pan,
	cp_VoicePitch,
	cp_LFO1Waveform,
	cp_LFO1Speed,
	cp_LFO1Mode,
	cp_LFO1Phase,
	cp_LFO1Sync,
	cp_LFO2Waveform,
	cp_LFO2Speed,
	cp_LFO2Mode,
	cp_LFO2Phase,
	cp_LFO2Sync,
	cp_Env1Attack,
	cp_Env1Decay,
	cp_Env1Sustain, //40
	cp_Env1Release,
	cp_Env1Amount,
	cp_Env2Attack,
	cp_Env2Decay,
	cp_Env2Sustain,
	cp_Env2Release,
	cp_Env2Amount,
	cp_FilterType,
	cp_FilterCutoff,
	cp_FilterResonance,
	cp_DistPreGain,
	cp_DistAmount,
	cp_DistColor,
	cp_DistType, //54
	cp_LastVoiceOne=cp_DistType,
	//Non-voice-specifics
	cp_Polyphony,
	cp_PortamentoSpeed,
	cp_ChannelLFOWaveform,
	cp_ChannelLFOSpeed,
	cp_ChannelLFOMode,
	cp_ChannelDistPreGain,
	cp_ChannelDistAmount,
	cp_ChannelDistColor,
	cp_ChannelDistType,
	cp_ChannelFilterType,
	cp_ChannelFilterCutoff,
	cp_ChannelFilterResonance,
	cp_ChannelPhaserAmount,
	cp_ChannelPhaserFrequency,
	cp_ChannelPhaserFeedback,
	cp_ChannelVolume,
	cp_ChannelFXRouting,
	cp_ChannelPan,
	cp_ReverbSend,
	cp_DelaySend,
	cp_ChannelBassBoost,
	cp_ChannelReserved1,
	cp_ChannelCompressorMode, //Off Peak RMS
	cp_ChannelCompressorThreshold,
	cp_ChannelCompressorRatio,
	cp_ChannelCompressorAttack,
	cp_ChannelCompressorRelease,
	cp_ChannelCompressorMakeupGain,
	cp_Mod1Source,
	cp_Mod1Dest,
	cp_Mod1Amount,
	cp_Mod2Source,
	cp_Mod2Dest,
	cp_Mod2Amount,
	cp_Mod3Source,
	cp_Mod3Dest,
	cp_Mod3Amount,
	cp_Mod4Source,
	cp_Mod4Dest,
	cp_Mod4Amount,
	cp_Mod5Source,
	cp_Mod5Dest,
	cp_Mod5Amount,
	cp_Mod6Source,
	cp_Mod6Dest,
	cp_Mod6Amount,
	cp_Mod7Source,
	cp_Mod7Dest,
	cp_Mod7Amount,
	cp_Mod8Source,
	cp_Mod8Dest,
	cp_Mod8Amount,
	cp_NumChannelParams,
	cps_OscSize = cp_Osc2Waveform - cp_Osc1Waveform,
	NumModulations = 8
};

enum GlobalParams {
	gp_Volume = cp_NumChannelParams,
	gp_ReverbVolume,
	gp_ReverbLength,
	gp_ReverbPole,
	gp_DelayAmount,
	gp_DelayPan,
	gp_DelayFeedback,
	gp_DelayLength,
	gp_GlobalLowCut,
	gp_GlobalHighCut,
	gp_GlobalCompressorMode, //Off Peak RMS
	gp_GlobalCompressorThreshold,
	gp_GlobalCompressorRatio,
	gp_GlobalCompressorAttack,
	gp_GlobalCompressorRelease,
	gp_GlobalCompressorMakeupGain,
	gp_NumGlobalAndChannelParams,
	gp_NumGlobalParams = gp_NumGlobalAndChannelParams - cp_NumChannelParams
};

enum ModulationSources {
	ms_Note = gp_NumGlobalAndChannelParams,
	ms_Velocity,
	ms_LFO1,
	ms_LFO2,
	ms_ChannelLFO,
	ms_Env1,
	ms_Env2,
	ParameterTableSize,
	ms_FirstModSource = ms_Note,
	ms_LastModSource = ms_Env2,
	hej = 0xFFFFFFFF
};


extern float parameterTable[ParameterTableSize];
extern int parameterTableInt[ParameterTableSize];

#ifndef STREAMLINED
extern const TCHAR *parameterNames[ParameterTableSize];




#endif
}

#endif